{% extends "base.html" %} {% block content %} {% load custom_filter %}
<!-- Modal -->
<div class="modal fade" id="edit_balancer" tabindex="-1" role="dialog">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="edit_balancer_title"></h4><small id="edit_balancer_mtitle"></small>
            </div>
            <div class="modal-body">
                <div class="nav-tabs-custom">
                    <ul class="nav nav-tabs">
                        <li class="active"><a href="#tab_base_config" data-toggle="tab" id="a_default_conf">基础配置</a></li>
                        <li><a href="#tab_ssl_config" data-toggle="tab">证书配置</a></li>
                        <li><a href="#tab_proxy_config" data-toggle="tab">节点配置</a></li>
                    </ul>
                    <div class="tab-content">
                        <div class="tab-pane active" id="tab_base_config">
                            <form class="form-horizontal" id="form_base_config">
                                <input type="text" name="proxy_config_id" id="input_proxy_config_id" hidden>
                                <div class="form-group">
                                    <label class="col-sm-2 control-label">名称</label>
                                    <div class="col-sm-9" id="div_proxy_name">
                                        <input type="text" class="form-control" name="proxy_proxy_name" id="input_proxy_proxy_name" placeholder="用于描述负载均衡器" onblur="check_form(this)">
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="col-sm-2 control-label">服务端口</label>
                                    <div class="col-sm-9" id="div_listen">
                                        <input type="text" class="form-control" name="proxy_listen" id="input_proxy_listen" placeholder="负载均衡器对外提供服务的监听端口" onblur="check_form(this)" data-inputmask="'mask':'[9]{1,5}'" data-mask>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="col-sm-2 control-label">访问域名</label>
                                    <div class="col-sm-9" id="div_server_name">
                                        <input type="text" class="form-control" name="proxy_server_name" id="input_proxy_server_name" placeholder="用于配置访问负载均衡器的域名（空格分隔）" onblur="check_form(this)">
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="col-sm-2 control-label">* 访问日志</label>
                                    <div class="col-sm-9">
                                        <input type="text" class="form-control" name="proxy_access_log" id="input_proxy_access_log" placeholder="此负载均衡器请求日志路径">
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="col-sm-2 control-label">* 错误日志</label>
                                    <div class="col-sm-9">
                                        <input type="text" class="form-control" name="proxy_error_log" id="input_proxy_error_log" placeholder="此负载均衡错误日志路径">
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="col-sm-2 control-label">* ip_hash</label>
                                    <div class="col-sm-9">
                                        <div class="checkbox">
                                            <label>
                                                <input type="checkbox" name="proxy_ip_hash" id="check_proxy_ip_hash"> 启用根据源地址引导流量
                                            </label>
                                        </div>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="col-sm-2 control-label">* 描述</label>
                                    <div class="col-sm-9">
                                        <textarea class="form-control" rows="4" name="proxy_description" id="input_proxy_description" placeholder="此负载均衡详细描述"></textarea>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <div class="col-sm-12">
                                        <span class="control-label pull-right">
                                            <small>负载均衡器基础配置（* 为可选项）</small>
                                        </span>
                                    </div>
                                </div>
                            </form>
                        </div>
                        <div class="tab-pane" id="tab_ssl_config">
                            <form class="form-horizontal" id="form_ssl_config">
                                <div class="form-group">
                                    <label class="col-sm-2 control-label">证书状态</label>
                                    <div class="col-sm-9">
                                        <div class="checkbox">
                                            <label>
                                                <input type="checkbox" name="ssl_status" id="check_ssl_status" onchange="check_balancer_ssl(this)"> 启用
                                            </label>
                                        </div>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="col-sm-2 control-label">保留原端口</label>
                                    <div class="col-sm-9">
                                        <div class="checkbox">
                                            <label>
                                                <input type="checkbox" name="ssl_port" id="check_ssl_port"> 启用
                                            </label>
                                        </div>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="col-sm-2 control-label">证书</label>
                                    <div id="div_ssl_cert_body" class="col-sm-9">
                                        <textarea class="form-control" rows="8" name="ssl_cert_body" id="txt_ssl_cert_body" placeholder="请粘贴证书文件（.crt）正文" onblur="check_form(this)" style="font-family:monospace;font-size:initial"></textarea>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="col-sm-2 control-label">私钥</label>
                                    <div id="div_ssl_key_body" class="col-sm-9">
                                        <textarea class="form-control" rows="8" name="ssl_key_body" id="txt_ssl_key_body" placeholder="请粘贴私钥文件（.key）正文" onblur="check_form(this)" style="font-family:monospace;font-size:initial"></textarea>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <div class="col-sm-12">
                                        <span class="control-label pull-right">
                                            <small>启用 HTTPS 访问方式配置</small>
                                        </span>
                                    </div>
                                </div>

                            </form>
                        </div>
                        <!-- /.tab-pane -->
                        <div class="tab-pane" id="tab_proxy_config">
                            <form class="form-horizontal" id="form_ssl_config">
                                <div class="form-group">
                                    <div class="col-sm-12">
                                        <a class="btn btn-primary btn-xs" href="#" onclick="edit_upstream(1,null)"><i class="fa fa-plus"> 增加节点</i></a>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <div class="col-sm-12">
                                        <table class="table table-bordered" style="margin-bottom:0px">
                                            <tr>
                                                <td class="col-sm-3">地址</td>
                                                <td class="col-sm-2">端口</td>
                                                <td class="col-sm-2">权重</td>
                                                <td class="col-sm-2">重试</td>
                                                <td class="col-sm-2">超时</td>
                                                <td></td>
                                            </tr>
                                        </table>
                                        <div id="div_upstream_list">
                                        </div>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <div class="col-sm-12">
                                        <span class="control-label pull-right">
                                            <small>后端服务器节点配置（* 为可选项）</small>
                                        </span>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                <button type="button" class="btn btn-primary" onclick="save_balancer()">保存</button>
            </div>
        </div>
    </div>
</div>


<div class="row">
    <div class="col-md-12">
        <div class="box box-primary">
            <div class="box-header with-border">
                <button type="button" class="btn btn-primary pull-left" onclick="edit_balancer(1)">创建负载均衡器</button>
                <div class="input-group pull-right" style="width: 250px;">
                    <input type="text" name="proxy_filter" id="input_proxy_filter" class="form-control pull-right" placeholder="请输入名称或域名" onkeydown='if(event.keyCode==13){proxy_filter()}'>
                    <div class="input-group-btn">
                        <button type="button" class="btn btn-default" onclick="proxy_filter()"><i class="fa fa-search"></i></button>
                    </div>
                </div>
            </div>
            <!-- /.box-header -->
            <div class="box-body no-padding">
                <table class="table table-striped">
                    <thead>
                        <tr>
                            <th>名称</th>
                            <th>协议</th>
                            <th>端口</th>
                            <th>状态</th>
                            <th>更新时间</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for server in proxy %}
                        <tr>
                            <td class="col-sm-3">
                                <button type="button" class="btn btn-default btn-xs col-sm-10" onclick="edit_balancer(0,'{{ server.config_id }}')">{{ server.proxy_name }}</button>
                            </td>
                            {% if server.protocols %}
                            <td><span class="label label-warning">HTTPS</span></td>
                            {% else %}
                            <td><span class="label label-primary">HTTP</span></td>
                            {% endif %}
                            <td>{{ server.listen }}</td>
                            {% if server.status %}
                            <td>
                                <button type="button" class="btn btn-success btn-xs" onclick="change_status('{{ server.pk }}',0)">启用</button>
                            </td>
                            {% else %}
                            <td>
                                <button type="button" class="btn btn-danger btn-xs" onclick="change_status('{{ server.pk }}',1)">禁用</button>
                            </td>
                            {% endif %}
                            <td>{{ server.update_time | timestamp_to_date }}</td>
                            <td>
                                <button type="button" class="btn btn-default btn-xs" onclick="delete_proxy('{{ server.pk }}','{{ server.proxy_name }}')">删除</button>
                            </td>
                        </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
            <!-- /.box-body -->
            <div class="box-footer clearfix">
                <ul class="pagination pagination-sm no-margin pull-right">
                    {% if proxy.has_previous %}
                    <li><a href="?page={{ proxy.previous_page_number }}&filter={{ filter }}" class="prev">{{ previous_link_decorator|safe }}上一页</a></li>
                    {% else %}
                    <li class="paginate_button previous disabled"><span class="disabled prev">{{ previous_link_decorator|safe }}上一页</span></li>
                    {% endif %}
                    {% if proxy.has_next %}
                    <li><a href="?page={{ proxy.next_page_number }}&filter={{ filter }}" class="next">下一页{{ next_link_decorator|safe }}</a></li>
                    {% else %}
                    <li class="paginate_button next disabled"><span class="disabled next">下一页{{ next_link_decorator|safe }}</span></li>
                    {% endif %}
                    <li class="paginate_button previous disabled">
                        <span>第 {{ proxy.number }} 页 - 共 {{ proxy.paginator.num_pages }} 页</span>
                    </li>
                </ul>
            </div>
        </div>
    </div>
</div>
<script>
    $('#menu_proxy_config').addClass('active')
    $('#page_header').text('负载均衡配置')
    $('#page_header_descript').text('用于管理 Nginx 虚拟主机相关配置')
    $('#page_nav').text('服务管理')
    $('#page_name').text('负载均衡配置')

    function check_form(_input) {
        var _input_div = $(_input.closest("div"))
        _input_div.removeClass('has-error')
        _input_div.removeClass('has-success')
        if (($(_input).val() == "") || ($(_input).attr('name') == "proxy_listen" && !$(_input).val().indexOf("8000"))) {
            _input_div.addClass('has-error')
        } else {
            _input_div.addClass('has-success')
        }
    }

    function check_balancer_ssl(_self) {
        if ($(_self)[0].checked == true) {
            $('#txt_ssl_cert_body').removeAttr('disabled')
            $('#txt_ssl_key_body').removeAttr('disabled')
            $('#check_ssl_port').removeAttr('disabled')
            $('#div_ssl_cert_body').removeClass('has-success')
            $('#div_ssl_key_body').removeClass('has-success')
        } else {
            $('#txt_ssl_cert_body').text('')
            $('#txt_ssl_key_body').text('')
            $('#check_ssl_port').prop('checked', false)
            $('#check_ssl_port').attr('disabled', 'disabled')
            $('#txt_ssl_cert_body').attr('disabled', 'disabled')
            $('#txt_ssl_key_body').attr('disabled', 'disabled')
        }
    }

    function edit_upstream(_add, _upstream) {
        if (_add == 1) {
            if (_upstream == null) {
                _upstream = {
                    address: null,
                    port: null,
                    weight: null,
                    max_fails: null,
                    fail_timeout: null
                }
            }

            _tb = '<form class="form-horizontal"><table class="table table-bordered" style="margin-bottom:0px"><tr>'
            _tb += '<td class="col-sm-3"><div><input type="text" onblur="check_form(this)" class="form-control" name="upstream_address" placeholder="IP地址" data-inputmask="\'alias\': \'ip\'" data-mask value="' + _upstream.address + '"></div></td>'
            _tb += '<td class="col-sm-2"><div><input type="text" onblur="check_form(this)" class="form-control" name="upstream_port" placeholder="服务端口" data-inputmask="\'mask\':\'[9]{1,5}\'" data-mask value="' + _upstream.port + '"></div></td>'
            _tb += '<td class="col-sm-2"><input type="text" class="form-control" name="upstream_weight" placeholder="*权重(1-100)" data-inputmask="\'mask\':\'[9]{1,3}\'" data-mask value="' + _upstream.weight + '"></td>'
            _tb += '<td  class="col-sm-2"><input type="text" class="form-control" name="upstream_max_fails" placeholder="*重试次数(1-99)"data-inputmask="\'mask\':\'[9]{1,2}\'" data-mask value="' + _upstream.max_fails + '"></td>'
            _tb += '<td class="col-sm-2"><input type="text" class="form-control" name="upstream_fail_timeout" placeholder="*超时时间(秒)" data-inputmask="\'mask\':\'[9]{1,2}\'" data-mask value="' + _upstream.fail_timeout + '"></td>'
            _tb += '<td><a href="#" onclick="edit_upstream(0,this)"><h5><i class="fa fa-remove"></i></h5></a></td>'
            _tb += '</tr></table></form>'
            $('#div_upstream_list').append(_tb)
            $("[data-mask]").inputmask()
        } else {
            $(_upstream).parents('form')[0].remove()
        }
    }


    function edit_balancer(_create, _config_id) {
        $('#a_default_conf').trigger('click')
        if (_create == 1) {
            $('#edit_balancer_title').text('创建负载均衡器')
            $('#input_proxy_config_id').val('0')
            $('#input_proxy_proxy_name').val('')
            $('#input_proxy_listen').val('')
            $('#input_proxy_server_name').val('')
            $('#input_proxy_access_log').val('')
            $('#input_proxy_error_log').val('')
            $('#check_proxy_ip_hash').attr('checked', false)
            $('#div_upstream_list').empty()
            $("[data-mask]").inputmask()
            $('#edit_balancer').modal('show')
        } else {
            var _post = {
                config_id: _config_id
            }
            jQuery.ajax({
                type: 'post',
                url: '/proxy/query/',
                data: JSON.stringify(_post),
                dataType: "json",
                success: function(p) {
                    if (p.flag == "Success") {
                        $('#edit_balancer_title').text('编辑负载均衡器')
                        $('#edit_balancer_mtitle').text(_config_id)
                        $('#input_proxy_config_id').val(_config_id)
                        $('#div_upstream_list').empty()

                        $('#input_proxy_proxy_name').val(p.content.proxy.proxy_name)
                        $('#input_proxy_listen').val(p.content.proxy.listen)
                        $('#input_proxy_server_name').val(p.content.proxy.server_name)
                        $('#input_proxy_access_log').val(p.content.proxy.access_log)
                        $('#input_proxy_error_log').val(p.content.proxy.error_log)
                        $('#input_proxy_description').text(p.content.proxy.description)
                        if (p.content.proxy.balancer_type == "ip_hash") {
                            $('#check_proxy_ip_hash').prop('checked', true)
                        } else {
                            $('#check_proxy_ip_hash').prop('checked', false)
                        }
                        for (var f in p.content.upstream) {
                            edit_upstream(1, p.content.upstream[f])
                        }
                        if (p.content.proxy.protocols == true) {
                            $('#check_ssl_status').prop('checked', true)
                            $('#txt_ssl_cert_body').text(p.content.proxy.ssl_cert)
                            $('#txt_ssl_key_body').text(p.content.proxy.ssl_key)
                        } else {
                            $('#check_ssl_status').prop('checked', false)
                        }
                        if (p.content.proxy.listen == 443) {
                            $('#check_ssl_port').prop('checked', false)
                        } else {
                            $('#check_ssl_port').prop('checked', true)
                        }
                        check_balancer_ssl($('#check_ssl_status'))
                        $('#edit_balancer').modal('show')
                    } else if (p.flag == "Error" && p.content == "AuthFailed") {
                        alert('认证失败！请重新登录！')
                        top.location = '/login/'
                    } else {
                        alert('查询失败！' + p.content)
                    }
                },
                error: function(e) {
                    alert('请求失败!')
                }
            })

        }
    }

    function delete_proxy(_pk, _name) {
        if (confirm("确认删除负载均衡[" + _name + "]？")) {
            var _post = {
                pk: _pk
            }
            jQuery.ajax({
                type: 'post',
                url: '/proxy/delete/',
                data: JSON.stringify(_post),
                dataType: 'json',
                success: function(p) {
                    if (p.flag == "Success") {
                        alert("删除成功!")
                        top.location = '/proxy/'
                    } else if (p.flag == "Error" && p.content == "AuthFailed") {
                        alert('认证失败！请重新登录！')
                        top.location = '/login/'
                    } else {
                        alert('删除错误！' + p.content)
                    }
                },
                error: function(e) {
                    alert('请求失败!')
                }
            })
        }
    }

    function change_status(_pk, _status) {
        if (confirm("确认要变更状态？")) {
            var _post = {
                pk: _pk,
                status: _status
            }
            jQuery.ajax({
                type: 'post',
                url: '/proxy/status/',
                data: JSON.stringify(_post),
                dataType: 'json',
                success: function(p) {
                    if (p.flag == "Success") {
                        alert("变更成功!")
                        top.location = '/proxy/'
                    } else if (p.flag == "Error" && p.content == "AuthFailed") {
                        alert('认证失败！请重新登录！')
                        top.location = '/login/'
                    } else {
                        alert('变更错误！' + p.content)
                    }
                },
                error: function(e) {
                    alert('请求失败!')
                }
            })
        }
    }

    function proxy_filter() {
        window.location = '/proxy/?filter=' + $('#input_proxy_filter').val()
    }

    function save_balancer() {
        if (confirm("确认要保存这样的配置？")) {
            var _base_config = $('#form_base_config').serializeObject()
            var _ssl_config = $('#form_ssl_config').serializeObject()
            var _upstream_list = []
            $('#div_upstream_list form').each(function() {
                _upstream_list.push($(this).serializeObject())
            })
            var _post = {
                'base_config': _base_config,
                'ssl_config': _ssl_config,
                'upstream_list': _upstream_list
            }

            jQuery.ajax({
                type: 'post',
                url: '/proxy/save/',
                data: JSON.stringify(_post),
                dataType: 'json',
                success: function(p) {
                    if (p.flag == "Success") {
                        alert("保存成功!")
                        top.location = '/proxy/'
                    } else if (p.flag == "Error" && p.content == "ArgsError") {
                        alert('保存失败！配置项填写错误！')
                    } else if (p.flag == "Error" && p.content == "NicError") {
                        alert('保存失败！内网网卡选择错误！')
                    } else if (p.flag == "Error" && p.content == "AuthFailed") {
                        alert('认证失败！请重新登录！')
                        top.location = '/login/'
                    } else {
                        alert('保存错误！其他错误：' + p.content)
                    }
                },
                error: function(e) {
                    alert('请求失败!')
                }
            })
        }

    }
</script>
{% endblock %}
